﻿using Common;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Threading;
using System.Xml.Linq;

namespace Common
{
    public class ClientAndServerHelper
    {
        #region Variables

        XDocument doc = new XDocument();
        string tempPath = "temp.xml";
        string autoupdateFile = "autoupdate.xml";
        MongoDBHelper mongo;
        AutoUpdateConfigModel updateXMLContent = new AutoUpdateConfigModel();
        LocalXMLModel localXML = new LocalXMLModel();
        static ClientAndServerHelper _instance;

        #endregion

        #region Constructor

        public ClientAndServerHelper()
        {
            try
            {
                LoadXML();
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
            }
        }

        #endregion

        #region Properties

        public static ClientAndServerHelper Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new ClientAndServerHelper();
                    if (_instance.LoadXML() == 1)
                    {
                        _instance.localXML = _instance.GetLocalXmlContent();
                        _instance.SetMongo(HospitalConfig.Instance.DicHospitals[_instance.localXML.Hospital]);
                        _instance.updateXMLContent = _instance.GetUpdateContent();
                    }
                }
                return _instance;
            }
        }

        public AutoUpdateConfigModel UpdateXMLContent
        {
            get
            {
                return updateXMLContent;
            }

            set
            {
                updateXMLContent = value;
            }
        }

        public LocalXMLModel LocalXMLContent
        {
            get
            {
                return localXML;
            }

            set
            {
                localXML = value;
            }
        }

        #endregion

        #region 依赖属性

        #endregion

        #region Event

        #endregion

        #region public Methods

        public void StartRestartExe()
        {
            try
            {
                foreach (string str in updateXMLContent.StartProcess)
                {
                    if (File.Exists(str))
                    {
                        Process.Start(str);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
                //throw new StartProcessFailedException();
            }
        }

        public void CheckCapServer()
        {
            if (Process.GetProcessesByName("syscc").Length == 0 || Process.GetProcessesByName("Monitor").Length == 0 || Process.GetProcessesByName("Anes").Length == 0)
            {
                ProcessHelper.KillProcessByName("syscc");
                ProcessHelper.KillProcessByName("Monitor");
                ProcessHelper.KillProcessByName("Anes");
                Process.Start("BCCap.exe");
            }
        }

        public string GetProName(string path)
        {
            try
            {
                return path.Substring(path.LastIndexOf('/') + 1);
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
                return "";
            }
        }

        public void RunExe(string exeName)
        {
            try
            {
                Process[] pros = Process.GetProcessesByName(exeName.Replace(".exe", ""));
                foreach (Process pro in pros)
                {
                    pro.CloseMainWindow();
                }
                Process.Start(exeName);
            }
            catch (Exception ex)
            {

                LogHelper.Error(this.GetType(), ex);
            }
        }

        public void DeleteZhiDingDir()
        {
            try
            {
                Task.Factory.StartNew((Action)delegate
                {

                    if (Directory.Exists(updateXMLContent.ZhiDingDir))
                    {
                        foreach (string pro in updateXMLContent.KillProcess)
                        {
                            ProcessHelper.KillProcessByName(pro);
                        }
                        Directory.Delete(updateXMLContent.ZhiDingDir, true);
                    }
                    updateXMLContent.IsDeleted = true;

                });
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
            }
            finally
            {

            }
        }

        /// <summary>
        /// 加载xml 1：成功 -1：文件不存在
        /// </summary>
        /// <returns></returns>
        public int LoadXML()
        {
            if (File.Exists(autoupdateFile))
            {
                try
                {
                    doc = XDocument.Load(autoupdateFile);
                    return 1;
                }
                catch (Exception ex)
                {
                    LogHelper.Error(this.GetType(), ex);
                    return -1;
                    throw new LoadXMLFailedException();
                }
            }
            else
            {
                return -1;
                throw new LoadXMLFailedException();
            }
        }

        public void KillAllProcesses()
        {
            try
            {
                Process currentPro = Process.GetCurrentProcess();
                foreach (string proName in updateXMLContent.KillProcess)
                {
                    ProcessHelper.KillProcessByName(proName, currentPro);
                    LogHelper.Fatal(this.GetType(), "KillProcessByName" + proName);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
            }
        }

        public void DownloadFiles(bool downloadRun, bool downloadStartExe, AutoUpdateConfigModel model = null)
        {
            try
            {
                if (model == null)
                {
                    model = updateXMLContent;
                }
                else
                {
                    foreach (var item in model.DownLoadFiles)
                    {
                        try
                        {
                            ProcessHelper.KillProcessByName(item.FielName);
                            mongo.DownloadFile(item.Id, item.FilePath);
                        }
                        catch (Exception ex)
                        {
                            LogHelper.Error(this.GetType(), ex);
                        }
                    }
                }

                if (downloadRun)
                {
                    ProcessHelper.KillProcessByName("Run");
                    mongo.DownloadFile(model.RunExeDownLoadPath, model.RunExeLocalPath);
                }
                if (downloadStartExe)
                {
                    ProcessHelper.KillProcessByName(model.StartExeName);
                    mongo.DownloadFile(model.StartExePath, model.StartExeLocalPath);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
            }
        }


        public AutoUpdateConfigModel GetUpdateContent()
        {
            try
            {
                return mongo.Find<AutoUpdateConfigModel>(FilterDefinition<AutoUpdateConfigModel>.Empty, "AutoUpdateConfig").OrderByDescending(O => O.ServerVersionId).FirstOrDefault();
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
                return new AutoUpdateConfigModel();
            }
        }

        public LocalXMLModel GetLocalXmlContent()
        {
            try
            {
                LocalXMLContent.LocalVersion = new Version(doc.Root.Element("Version").Value);
                LocalXMLContent.Hospital = doc.Root.Element("Hospital").Value;
                LocalXMLContent.SerIp = doc.Root.Element("UpdateServer").Element("Ip").Value;
                if (string.IsNullOrEmpty(LocalXMLContent.SerIp))
                {
                    LocalXMLContent.SerIp = HospitalConfig.Instance.DicHospitals[LocalXMLContent.Hospital].Ip;
                }
                LocalXMLContent.FtpSerUri = LocalXMLContent.SerIp + ":" + doc.Root.Element("UpdateServer").Element("Port").Value;
                LocalXMLContent.RoomId = doc.Root.Element("RoomId").Value;
                LocalXMLContent.LoginId = doc.Root.Element("LoginId").Value;
                
                return LocalXMLContent;
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
                return new LocalXMLModel();
            }
        }

        public void ProcessStartExe()
        {
            try
            {
                Process.Start(updateXMLContent.RealStartExePath);
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
            }
        }

        public void WriteVersionToLocal()
        {
            try
            {
                doc.Root.Element("Version").SetValue(updateXMLContent.ServerVersion);
                doc.Save(autoupdateFile);
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
            }
        }

        #endregion

        #region Public/public Methods

        public void SetMongo(Hospital hospital)
        {
            mongo = new MongoDBHelper(hospital.Ip, hospital.Port, hospital.DbName);
        }

        public void WrtiteRoomToLocal(string roomId)
        {
            try
            {
                localXML.RoomId = roomId;
                doc.Root.Element("RoomId").SetValue(roomId);
                doc.Save(autoupdateFile);
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
            }
        }
        public void WrtiteLoginNameToLocal(string loginId)
        {
            try
            {
                if (doc.Root.Element("LoginId") != null)
                {
                    localXML.LoginId = loginId;
                    doc.Root.Element("LoginId").SetValue(loginId);
                    doc.Save(autoupdateFile);
                }
                else
                {
                    localXML.LoginId = loginId;
                    XElement loginElement = new XElement("LoginId");
                    loginElement.SetValue(loginId);
                    doc.Root.Add(loginElement);
                    doc.Save(autoupdateFile);
                }

            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
            }
        }

        #endregion

        #region EventHandlers

        #endregion

    }
}